package com.oraro.paygatewaybiz.channel.alipay.serviceImpl;

import com.alipay.api.AlipayApiException;
import com.netflix.discovery.converters.Auto;
import com.oraro.common.result.Result;
import com.oraro.middleservice.logger.starter.supports.BizLoggerHelper;
import com.oraro.paygatewaybiz.channel.alipay.interfaces.AliPayService;
import com.oraro.paygatewaybiz.channel.alipay.proxy.AliPayServiceProxy;
import com.oraro.paygatewaybiz.constant.Constants;
import com.oraro.paygatewaybiz.exception.AliNotifyException;
import com.oraro.paygatewaybiz.interfaces.PayChannelService;
import com.oraro.paygatewaybiz.module.entity.ChannelEntity;
import com.oraro.paygatewaybiz.module.entity.MchEntity;
import com.oraro.paygatewaybiz.module.entity.OrderEntity;
import com.oraro.paygatewaybiz.module.service.ChannelService;
import com.oraro.paygatewaybiz.module.service.MchService;
import com.oraro.paygatewaybiz.module.service.OrderService;
import com.oraro.paygatewaybiz.utils.HttpsUtils;
import com.oraro.paygatewaybiz.utils.OrderValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;


/**
 * @Author: jianghuiyong
 * @Date: 2018/11/16 11:07
 * @Version 1.0
 */
@Service
@Slf4j
public class AliPayChannelServiceImpl extends AbstractAliBaseService implements PayChannelService {

    @Autowired
    private AliPayServiceProxy aliPayServiceProxy;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private MchService mchService;
    @Autowired
    private BizLoggerHelper bizLoggerHelper;

    @Override
    public String type() {
        return Constants.PayChannelType.ALIPAY.getType();
    }

    @Override
    public Result payOrder(OrderEntity orderEntity, ChannelEntity channelEntity) {
        return aliPayServiceProxy.payOrder(orderEntity, channelEntity);
    }

    @Override
    public String handleNotify(Map<String, String> notifyMap, String channelType) {

        ChannelEntity channelEntity = channelService.getChannelByAppId(notifyMap.get("app_id"));
        if (channelEntity == null) {
//            log.error("支付宝渠道错误,订单号:{}", notifyMap.get("out_trade_no"));
            throw new AliNotifyException(String.format("支付宝渠道错误,订单号:{}", notifyMap.get("out_trade_no")));
        }
        //验证签名
        boolean flag = false;
        try {
            flag = aliSignCheck(notifyMap, channelEntity.getAlipayPublicKey());
        } catch (AlipayApiException e) {
//            log.error("支付宝签名验证失败,订单号:{}", notifyMap.get("out_trade_no"));
            throw new AliNotifyException(String.format("支付宝签名验证失败,订单号:{}", notifyMap.get("out_trade_no")));
        }

        if (flag) {
            // 交易类型
            String trade_status = notifyMap.get("trade_status");

            if ("TRADE_FINISHED".equals(trade_status)) {
                //TODO
            } else if ("TRADE_SUCCESS".equals(trade_status)) {                 //支付成功，执行业务处理
                OrderEntity orderEntity = orderService.getByTradeNo(notifyMap.get("out_trade_no"));
                if (orderEntity == null) {
//                    log.error("支付宝订单不存在,订单号:{}", notifyMap.get("out_trade_no"));
                    throw new AliNotifyException(String.format("支付宝订单不存在,订单号:{}", notifyMap.get("out_trade_no")));
                } else if (orderEntity.getPayStatus() == 0) {
                    //验证本地订单金额
                    long totalAmount = convertDollar2Cent(Double.valueOf(notifyMap.get("total_amount")));
                    if ( totalAmount != orderEntity.getTotalFee()) {
//                        log.error("支付宝订单金额错误,订单号:{}", orderEntity.getOutTradeNo());
                        throw new AliNotifyException(String.format("支付宝订单金额错误,订单号:{}", orderEntity.getOutTradeNo()));
                    }
                    //完成本地订单
                    orderService.completeOrder(orderEntity);
                    bizLoggerHelper.log("==========完成支付宝订单===========订单号===:" +  orderEntity.getOutTradeNo());

                    //回调应用接口
                    MchEntity mchEntity = mchService.getById(orderEntity.getMchId());
                    try {
                        Map<String, String> map = OrderValidator.generateNotifyParam(orderEntity, mchEntity.getMchKey());
                        notifyParam(channelEntity.getNotifyUrl(), map);
                    } catch (Exception e) {
                        log.error(e.toString());
//                        log.error("支付回调本地服务失败,订单号:{}" + orderEntity.getOutTradeNo());
                        throw new AliNotifyException(String.format("支付回调本地服务失败,订单号:{}" + orderEntity.getOutTradeNo()));
                    }
                }
            }
        } else {
//            log.error("支付宝签名验证失败:{}", notifyMap.get("out_trade_no"));
            throw new AliNotifyException(String.format("支付宝签名验证失败:{}", notifyMap.get("out_trade_no")));
        }

        return Constants.RETURN_ALIPAY_VALUE_SUCCESS;
    }

    @Async
    public void notifyParam (String url, Map<String, String> map) {
        HttpsUtils.doPost(url, map);
    }


}
